from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
import pytest
from httprunner import Parameters
"""
httprunner：这是一个三方库
HttpRunner：类名，所有的测试用例类，必须继承HttpRunner
Config：全局配置文件，可以设置全局的url、忽略https警告、全局变量等
Step：每一条step就是一条接口
RunRequest：每一条测试用例的具体内容，包含：请求方式、请求地址、请求参数（headers、body）、断言内容
RunTestCase：用于解耦文件的调用。比如A文件写好后，B文件可以通过调用A文件来实现后续的用例步骤
"""

"""
httprunner命名规范：
py文件必须是_test结尾，或者是test_开头
定义的测试类，需要继承httprunner
teststeps为测试步骤，每一个测试步骤叫做step
step里的RunRequest，是待测的API名字，可按照接口名称填写
"""


class TestCaseCrmeb2(HttpRunner):  # 所有的测试类，必须继承HttpRunner
    # 单组数据驱动

    # @pytest.mark.parametrize(
    #     'param',Parameters({'username':['admin','admin1','admin2'],})
    # )
    # def test_start(self,param):
    #     super().test_start(param)
    @pytest.mark.parametrize('param', Parameters(
        {"username": "${get_userName()}", 'password': ['123', '1234', '920509'], }
        ))
    def test_start(self, param):
        super().test_start(param)
    """
    第一组：admin  ，123
    第二组：admin，1234
    第三组：admin，920509
    第四组：admin1，123
    第五组：admin1，1234
    第六组：admin1，920509
    第七组：admin2，123
    第八组：admin2，1234
    第九组：admin2，920509
    """
    """
    config:全局配置
    """
    config = Config("crmeb测试用例").verify(False).variables(**{"user": "$username", "pwd": "$password"}).base_url(
        "http://8.140.193.160:8899")
    """
    .variables(**{"user":"admin","pwd":"920509"}) ：定义了两个全局变量，整篇的文件都可以引用到
    .verify(False)  ：忽略https证书警告
    .base_url("http://8.140.193.160:8899")：设置全局的URL，后续都受用
    """
    teststeps = [
        Step(  # Step表示这是一条接口用例
            RunRequest("登录").  # 给这条接口命名，可以是中文
                with_variables(**{"code": 200}).  # 定义局部变量，仅限于当前step中可以用
                post("http://8.140.193.160:8899/adminapi/login").  # post请求方式，里面内容填写请求地址
                with_json({'account': '$user', 'pwd': '${pwd}', 'imgcode': 'a'}).  # $ 引用定义好的变量
                extract().  # 后续取出参数的方法
                with_jmespath("body.data.token", "token").  # 取出响应体的参数，后续用作接口关联。   body.data.token是表达式，token是变量命名
                with_jmespath("body.data.menus[0].icon", "icon").
                validate().
                assert_equal("status_code", "$code").  # 前面是从接口响应拿出的值，后面是预期的结果

                assert_equal('headers."Content-Type"', "application/json; charset=utf-8").
                assert_equal("body.status", 200).
                assert_greater_than("body.status", 199).  # 判断是否大于199
                assert_endswith("body.msg", 'k').  # 判断取出的字符串末尾是否是k
                assert_equal("body.msg", "ok").
                assert_startswith("body.msg", "o").  # 判断取出的字符串开始是否是o
                assert_equal("body.data.menus[0].path", "/admin/home/")
        ),

        Step(
            RunRequest("用户分组查询").
                get("/adminapi/user/user_group/list").
                with_params(**{'page': '1', 'limit': '15'}).
                with_headers(**{'Authori-zation': 'Bearer $token'}).  # 引用上面取出来的参数
                validate().
                assert_equal("status_code", 200).
                assert_equal('headers."Content-Type"', "application/json; charset=utf-8").
                assert_equal("body.status", 200).
                assert_equal("body.msg", "ok")),

    ]


if __name__ == "__main__":
    TestCaseCrmeb2().test_start()
